package com.guard.agent.plugin.springboot;

import com.guard.agent.bridge.AgentContext;
import com.guard.agent.bridge.PluginClassLoaderFactory;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.implementation.bytecode.assign.Assigner;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class SpringBootAdvice {

    @Advice.OnMethodEnter
    public static Object enter(@Advice.This(optional = true) Object invoker,
                               @Advice.Origin("#t") String className,
                               @Advice.Origin("#m") String methodName,
                               @Advice.Origin Class clazz,
                               @Advice.Origin Method method,
                               @Advice.AllArguments(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object[] args,
                               @Advice.Local("guardagent_context") Map context,
                               @Advice.Local("guardagent_context2") Map context2) throws Exception {
        Class interceptor = Class.forName("com.guard.agent.plugin.springboot.SpringBootInterceptor", true, PluginClassLoaderFactory.get(clazz.getClassLoader()));
        Object instance = interceptor.newInstance();
        interceptor.getDeclaredMethod("before").invoke(instance);

        context = new HashMap();
        context.put("11", "22");
        System.out.println(context);

        context2 = new HashMap();
        context2.put("22", "33");
        System.out.println(context2);
        return instance;
    }

    @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
    public static void exit(
            @Advice.Enter Object interceptor,
            @Advice.This(optional = true) Object invoker,
            @Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result,
            @Advice.Thrown(readOnly = false, typing = Assigner.Typing.DYNAMIC) Throwable throwable,
            @Advice.Local("guardagent_context") Map context,
            @Advice.Local("guardagent_context2") Map context2) throws Exception {
        interceptor.getClass().getDeclaredMethod("after").invoke(interceptor);
        System.out.println(context);
        System.out.println(context2);
    }

}
